import { useCallback, useEffect, useRef, ChangeEvent } from "react";
import { message, RadioChangeEvent } from 'antd';
import dayjs from 'dayjs';


const toastShort = (type: 'info' | 'warning' | 'error' | 'loading' | 'success', content: string, duration?: number) => {
    if (!duration) {
        duration = 1.5;
    }
    message[type](content, duration);
};

const makeClassNameList = (classNameList: Array<string | any>) => {
    try {
        let classNameStr = '';
        classNameList.forEach(className => {
            if (className) {
                classNameStr = classNameStr + ' ' + className;
            }
        })
        // console.log("classNameStr", classNameStr);
        return classNameStr
    } catch (e) {
        return '';
    }
}

const colorRGB2Hex = (color: string) => {
    var rgb = color.split(',');
    var r = parseInt(rgb[0].split('(')[1]);
    var g = parseInt(rgb[1]);
    var b = parseInt(rgb[2].split(')')[0]);

    var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
    return hex;
}

const hexToRgba = (hex: string, opacity: number) => {
    var RGBA = "rgba(" + parseInt("0x" + hex.slice(1, 3)) + "," + parseInt("0x" + hex.slice(3, 5)) + "," + parseInt("0x" + hex.slice(5, 7)) + "," + opacity + ")";
    return {
        red: parseInt("0x" + hex.slice(1, 3)),
        green: parseInt("0x" + hex.slice(3, 5)),
        blue: parseInt("0x" + hex.slice(5, 7)),
        rgba: RGBA
    }
}

const deepCopy = (value: any) => {
    try {
        return JSON.parse(JSON.stringify(value));
    } catch (e) {
        return ''
    }
};


const forEachValue = (obj: any, fn: any) => Object.keys(obj).forEach(key => fn(obj[key], key))

function _useDebounce(fn: any, delay: any, dep: Array<any> = []) {
    const { current } = useRef({ fn, timer: null });
    useEffect(function () {
        current.fn = fn;
    }, [fn]);
    //@ts-ignore
    return useCallback(function f(...args) {
        if (current.timer) {
            //@ts-ignore
            clearTimeout(current.timer);
        }
        //@ts-ignore
        current.timer = setTimeout(() => {
            //@ts-ignore
            current.fn.call(this, ...args);
        }, delay);
    }, dep)
};

function debounce(fn: Function, ms: number) {
    let timer: any = null;
    //@ts-ignore
    return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn(...args);
        }, ms);
    }
}


function useDebounce(fn: Function, ms: number) {
    const fRef = useRef();
    //@ts-ignore
    fRef.current = fn;
    const result = useCallback(
        //@ts-ignore
        debounce(() => fRef.current(), ms),
        []);
    return result;
}

const getChangeEventValue = (e: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement> | ChangeEvent<RadioChangeEvent> | RadioChangeEvent): string => {
    try {
        //@ts-ignore
        return e.target.value;
    } catch (err) {
        return "";
    }
}

const isEmpty = (value: any) => {
    try {
        if (value === null || value === undefined || value === "" || JSON.stringify(value) === '{}') {
            return true
        };
        return false;
    } catch (e) {
        return true;
    }
};

const commonErrorMsg = "操作失败，请稍后重试!";
const commonSuccessMsg = "操作成功!";

const addKeyToList = (list: Array<any>) => {
    let originList = list;
    originList.forEach((ele, index) => {
        ele.key = ele.id ? ele.id : index + '';
        // ele.deletePopConfirmOpened = false;
    })
    return originList;
};

const formatTime = (ns: any) => {
    return dayjs(new Date(ns).getTime()).format('YYYY-MM-DD HH:mm')
}

/**
 * list 转 tree 方法1
 * @param originList 
 * @returns 
 */
const generateTreeData = (originList: Array<any>): Array<any> => {
    const [map, treeData] = [{}, []];
    for (let i = 0; i < originList.length; i += 1) {
        map[originList[i].id] = i;
        originList[i].children = [];
    }
    for (let i = 0; i < originList.length; i += 1) {
        const node = originList[i];
        if (node.pid && originList[map[node.pid]]) {
            originList[map[node.pid]].children.push(node);
        } else {
            treeData.push(node);
        }
    }
    return treeData;
};

/**
 * list 转 tree 方法2
 * @param list 
 * @returns 
 */
const list2Tree = (list: Array<any>) => {
    const tree = []
    for (const node of list) {
        // 如果没有pid就可以认为是根节点
        if (!node.pid) {
            let p = { ...node }
            p.children = getChildren(p.id, list)
            tree.push(p)
        }
    }
    function getChildren(id, list) {
        const children = []
        for (const node of list) {
            if (node.pid === id) {
                children.push(node)
            }
        }

        for (const node of children) {
            const children = getChildren(node.id, list)
            if (children.length) {
                node.children = children
            }
        }

        return children
    }

    return tree
}


/**
 * 树转列表
 * @param tree 
 * @returns 
 */
const tree2List = (tree) => {
    const list = []
    const queue = [...tree]
    while (queue.length) {
        const node = queue.shift()
        const children = node.children
        if (children) {
            queue.push(...children)
        }
        list.push(node)
    }
    return list
}


const addTreePropertyForList = (originList: Array<any>): any[] => {
    console.log("addTreePropertyForList--->", originList)
    let resultList = originList.map(ele => {
        ele.title = ele.name ? ele.name : ele.name;
        ele.key = ele.id;
        ele.pid = ele.pid ? ele.pid : 0;
        return ele;
    })
    return resultList;
}


const getUuid = (len: number, radix?: number) => {
    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
    let uuid = []
    let i
    radix = radix || chars.length
    if (len) {
        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
    } else {
        let r
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
        uuid[14] = '4'
        for (i = 0; i < 36; i++) {
            if (!uuid[i]) {
                r = 0 | Math.random() * 16
                uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]
            }
        }
    }
    let NS = (new Date().getTime() / 1000).toFixed(0);
    // return uuid.join('') + '-' + NS;
    return uuid.join('');
}

const adaptTopicLevel = (level: string): string => {
    let topicLevelText = '';
    switch (level) {
        case '1':
            topicLevelText = '一级';
            break;
        case '2':
            topicLevelText = '二级';
            break;
        case '3':
            topicLevelText = '三级';
            break;
        case '4':
            topicLevelText = '四级';
            break;
        case '5':
            topicLevelText = '五级';
            break;
        case '6':
            topicLevelText = '六级';
            break;
        default:
            break;
    }
    return topicLevelText;
}


const preProcessParams = (params: Object): any => {
    Object.keys(params).forEach(item => {
        if (isEmpty(params[item])) {
            delete params[item];
        }
    })
    return params;
}

const phoneRE = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/

const handleDownloadByName = (url: string, downLoadFileName: string, openNewWindow?: boolean) => {
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = url
    link.setAttribute(
        'download',
        downLoadFileName ? downLoadFileName : "未命名文件"
    )
    console.log("link---->", link)
    if (openNewWindow) {
        link.target = "_new";
    }
    document.body.appendChild(link)
    link.click()
};

const checkTwoArraryEquals = (list1: any[], list2: any[]): boolean => {
    let result = true;
    if (list1.length !== list2.length) {
        result = false;
        return result;
    }
    list1.forEach((item, itemIndex) => {
        if (list2[itemIndex] !== undefined) {
            if (JSON.stringify(item) != JSON.stringify(list2[itemIndex])) {
                result = false;
            } else {
                result = true;
            }
        } else {
            result = false;
        }
    })
    //@ts-ignore
    if (result == false) {
        console.log("不相等的数组", list1, list2)
    }
    return result;
}

const getUniqueStringList = (list: string[]): string[] => {
    let resultList: string[] = [];
    list.forEach(ele => {
        if (!resultList.includes(ele)) {
            resultList.push(ele);
        }
    })
    return resultList;
};


const getSingleTdTableHeight = (height: number): number => {
    let tableContainerHeight = height && height > 50 ? height - 47 : 0;
    return tableContainerHeight;
}

const adaptUnit = (unit: string) => {
    switch (unit) {
        case 'm2':
            return '㎡';
            break;
        case 'm3':
            return 'm³';
            break;
        case 'hm2':
            return 'h㎡';
            break;
        default:
            return unit;
            break;
    }
}

const parsePrice = (value: number) => {
    return Number(value).toFixed(2)
}

const replaceUnitUpperCase = (str: string) => {
    try {
        const regex = /(m2|m3)/g;
        let resultStr = str.replace(regex, (matched) => {
            return matched === "m2" ? "㎡" : "m³";
        })
        return resultStr;
    } catch (e) {
        return str;
    }
}

const swapListElements = (arr: any[], index1: number, index2: number): any[] => {
    if (index1 !== index2 && index1 >= 0 && index2 >= 0 && index1 < arr.length && index2 < arr.length) {
        [arr[index1], arr[index2]] = [arr[index2], arr[index1]];
    }
    return arr;
}


const findLast = (arr: any[], callback: Function) => {
    return arr.reduceRight((prev, cur, index) => {
        if (prev !== undefined) {
            return prev;
        }
        if (callback(cur, index, arr)) {
            return cur;
        }
    }, undefined);
}

const removeNode = (tree, targetId) => {
    if (!tree || !tree.length) {
        return;
    }
    for (let i = 0; i < tree.length; i++) {
        if (tree[i].id === targetId) {
            tree.splice(i, 1);
            return;
        } else if (tree[i].children && tree[i].children.length > 0) {
            removeNode(tree[i].children, targetId);
        }
    }
}

const removeNodeWithPid = (data: any, targetId) => {
    // 从数组中移除节点及其所有子节点
    function removeNodeRecursive(id: any) {
        const removedNodes = data.filter(node => node.pid === id);
        for (let removedNode of removedNodes) {
            removeNodeRecursive(removedNode.id);
        }
        data = data.filter(node => node.id !== id);
    }
    // 移除指定的目标节点及其所有子节点
    removeNodeRecursive(targetId);
    return data;
}


const distributionLocationPoint = (locationPoint: string) => {
    locationPoint = locationPoint + '';
    var i = locationPoint.indexOf('.');
    var strDu = i < 0 ? locationPoint : locationPoint.substring(0, i);//获取度
    var strFen = 0;
    var strMiao = 0;
    if (i > 0) {
        //@ts-ignore
        var strFen = "0" + locationPoint.substring(i);
        //@ts-ignore
        strFen = strFen * 60 + "";
        //@ts-ignore
        i = strFen.indexOf('.');
        if (i > 0) {
            //@ts-ignore
            strMiao = "0" + strFen.substring(i);
            //@ts-ignore
            strFen = strFen.substring(0, i);//获取分
            //@ts-ignore
            strMiao = strMiao * 60 + "";
            //@ts-ignore
            i = strMiao.indexOf('.');
            //@ts-ignore
            strMiao = strMiao.substring(0, i + 4);//取到小数点后面三位
            //@ts-ignore
            strMiao = parseFloat(strMiao).toFixed(2);//精确小数点后面两位
        }
    }
    return strDu + "°" + strFen + "′" + strMiao;
};


const adaptLocationPoint = (longitude: number | string, latitude: number | string) => {
    try {
        if (longitude && latitude) {
            //@ts-ignore
            return `${distributionLocationPoint(longitude)}″E  ${distributionLocationPoint(latitude)}″N`
        } else {
            return "暂无定位"
        }
    } catch (e) {
        return "格式化坐标信息失败"
    }
};


const mapZoomStepInfoList = [
    {
        zoom: 0,
        realDistance: '5000',  //公里
        px: '70', //像素精度
        mapSize: '2.47厘米',
        dpi: '72',
        scale: '2亿',
        spaceDistance: '71公里',
        viewPointHeight: '17372公里',
    },
    {
        zoom: 1,
        realDistance: '5000',  //公里
        px: '70', //像素精度
        mapSize: '2.47厘米',
        dpi: '72',
        scale: '2亿',
        spaceDistance: '71公里',
        viewPointHeight: '14246公里',
    },
    {
        zoom: 2,
        realDistance: '5000',  //公里
        px: '70', //像素精度
        mapSize: '2.47厘米',
        dpi: '72',
        scale: '2亿',
        spaceDistance: '71公里',
        viewPointHeight: '10123千米',
    },
    {
        zoom: 3,
        realDistance: '2000',  //公里
        px: '55', //像素精度
        mapSize: '1.94厘米',
        dpi: '72',
        scale: '1亿',
        spaceDistance: '36公里',
        viewPointHeight: '7123公里',
    },
    {
        zoom: 4,
        realDistance: '2000',  //公里
        px: '115', //像素精度
        mapSize: '4.06厘米',
        dpi: '72',
        scale: '5千万',
        spaceDistance: '17公里',
        viewPointHeight: '6321公里',
    },
    {
        zoom: 5,
        realDistance: '1000',  //公里
        px: '115', //像素精度
        mapSize: '4.06厘米',
        dpi: '72',
        scale: '2.5千万',
        spaceDistance: '9公里',
        viewPointHeight: '5522公里',
    },
    {
        zoom: 6,
        realDistance: '500',  //公里
        px: '115', //像素精度
        mapSize: '4.06厘米',
        dpi: '72',
        scale: '1.2千万',
        spaceDistance: '4公里',
        viewPointHeight: '3436',
    },
    {
        zoom: 7,
        realDistance: '200',  //公里
        px: '91', //像素精度
        mapSize: '3.21厘米',
        dpi: '72',
        scale: '6百万',
        spaceDistance: '2公里',
        viewPointHeight: '539',
    },
    {
        zoom: 8,
        realDistance: '100',  //公里
        px: '176', //像素精度
        mapSize: '6.21厘米',
        dpi: '72',
        scale: '160万',
        spaceDistance: '568米',
        viewPointHeight: '305',
    },
    {
        zoom: 9,
        realDistance: '50',  //公里
        px: '91', //像素精度
        mapSize: '3.21厘米',
        dpi: '72',
        scale: '155万',
        spaceDistance: '549米',
        viewPointHeight: '180',
    },
    {
        zoom: 10,
        realDistance: '20',  //公里
        px: '72', //像素精度
        mapSize: '2.54厘米',
        dpi: '72',
        scale: '80万',
        spaceDistance: '278米',
        viewPointHeight: '133',
    },
    {
        zoom: 11,
        realDistance: '10',  //公里
        px: '72', //像素精度
        mapSize: '2.54厘米',
        dpi: '72',
        scale: '40万',
        spaceDistance: '139米',
        viewPointHeight: '100',
    },
    {
        zoom: 12,
        realDistance: '10',  //公里
        px: '72', //像素精度
        mapSize: '2.54厘米',
        dpi: '72',
        scale: '40万',
        spaceDistance: '139米',
        viewPointHeight: '76.5',
    },
    {
        zoom: 13,
        realDistance: '2',  //公里
        px: '57', //像素精度
        mapSize: '2.01厘米',
        dpi: '72',
        scale: '10万',
        spaceDistance: '35米',
        viewPointHeight: '58.2',
    },
    {
        zoom: 14,
        realDistance: '2',  //公里
        px: '118', //像素精度
        mapSize: '4.16厘米',
        dpi: '72',
        scale: '5万',
        spaceDistance: '17米',
        viewPointHeight: '23.5',
    },
    {
        zoom: 15,
        realDistance: '1',  //公里
        px: '118', //像素精度
        mapSize: '4.16厘米',
        dpi: '72',
        scale: '2.5万',
        spaceDistance: '8米',
        viewPointHeight: '9.6',
    },
    {
        zoom: 16,
        realDistance: '0.5',  //公里
        px: '118', //像素精度
        mapSize: '4.16厘米',
        dpi: '72',
        scale: '1.2万',
        spaceDistance: '4米',
        viewPointHeight: '4',
    },
    {
        zoom: 17,
        realDistance: '0.2',  //公里
        px: '93', //像素精度
        mapSize: '3.28厘米',
        dpi: '72',
        scale: '0.6',
        spaceDistance: '2.15米',
        viewPointHeight: '2',
    },
    {
        zoom: 18,
        realDistance: '0.1',  //公里
        px: '93', //像素精度
        mapSize: '3.28厘米',
        dpi: '72',
        scale: '0.3',
        spaceDistance: '1.07米',
        viewPointHeight: '1.7',
    },
    {
        zoom: 19,
        realDistance: '0.05',  //公里
        px: '93', //像素精度
        mapSize: '3.28厘米',
        dpi: '72',
        scale: '0.15',
        spaceDistance: '0.54米',
        viewPointHeight: '1.5',
    },
    {
        zoom: 20,
        realDistance: '0.02',  //公里
        px: '20', //像素精度
        mapSize: '3.28厘米',
        dpi: '72',
        scale: '0.08',
        spaceDistance: '0.27米',
        viewPointHeight: '1',
    },
]


export {
    makeClassNameList,
    colorRGB2Hex,
    hexToRgba,
    deepCopy,
    _useDebounce,
    useDebounce,
    getChangeEventValue,
    toastShort,
    isEmpty,
    commonErrorMsg,
    commonSuccessMsg,
    addKeyToList,
    formatTime,
    generateTreeData,
    getUuid,    
    adaptTopicLevel,
    addTreePropertyForList,
    tree2List,
    preProcessParams,
    phoneRE,
    handleDownloadByName,
    checkTwoArraryEquals,
    getUniqueStringList,
    getSingleTdTableHeight,
    adaptUnit,
    parsePrice,
    replaceUnitUpperCase,
    swapListElements,
    findLast,
    removeNode,
    removeNodeWithPid,
    adaptLocationPoint,
    mapZoomStepInfoList
}